﻿using CaseManagerLibrary.Auth;
using CaseManagerLibrary.Http;
using CaseManagerLibrary.Log;
using CaseManagerLibrary.Models;
using CaseManagerLibrary.Socket;
using CaseManagerLibrary.WinSystem;
using NetSDKCS;
using PSDClientService.SystemSettings;
using PSDLib;
using PSDLib.Download;
using PSDLib.Models;
using PSDLib.Protocols;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PSDClientService.Download
{
    public class DownloadContext
    {
        public bool Running { get; set; }
        public bool Downloading { get; set; }
        public object lock_Downloading = new object();

        //public static object lock_Progressing = new object();

        public bool Closing { get; set; }

        public string UUID
        {
            get
            {
                return ClientContext.UUID;
            }
            set
            {
                ClientContext.UUID = value;
            }
        }

        public dl_download_device Device
        {
            get
            {
                return ClientContext.Device;
            }
            set
            {
                ClientContext.Device = value;
            }
        }

        public ClientServiceContext ClientContext { get; set; }
        //public MessageManager MessageManager { get; set; }
        //public HeartbeatManager HeartbeatManager { get; set; }
        //public DeviceManager DeviceManager { get; set; }
        //public TaskManager TaskManager { get; set; }
        public DailyDownloadManager DownloadManager { get; set; }

        public CaseLogDownloadManager CaseLogManager { get; set; }

        public LocalDataManager LocalDataManager { get; set; }

        public ErrorFileManager_v2 ErrorFileManager { get; set; }
        public ILog Logger
        {
            get
            {
                return ClientContext.Logger;
            }
        }

        public string UserName { get; set; }
        public string Password { get; set; }
        public bool RunAsService { get; set; }
        public string LogType { get; set; }

        public DownloadContext(ClientServiceContext clientContext)
        {
            Running = false;
            Closing = false;
            Downloading = false;

            ClientContext = clientContext;

            //MessageManager = new MessageManager(this);
            //DeviceManager = new DeviceManager(this);
            //TaskManager = new TaskManager(this);
            DownloadManager = new DailyDownloadManager(this);
            CaseLogManager = new CaseLogDownloadManager(this);
            //HeartbeatManager = new HeartbeatManager(this);
            LocalDataManager = new LocalDataManager(this);
            ErrorFileManager = new ErrorFileManager_v2(this);
        }

        public HResult Init(bool runAsService)
        {
            RunAsService = runAsService;

            HResult result = new HResult() { success = true };

            //if (!DeviceManager.Init())
            //{
            //    result.success = false;
            //    result.message = "DeviceManager Init Failed";
            //    return result;
            //}

            //if (!MessageManager.Init())
            //{
            //    result.success = false;
            //    result.message = "MessageManager Init Failed";
            //    return result;
            //}

            if (!DownloadManager.Init())
            {
                result.success = false;
                result.message = "DownloadManager Init Failed";
                return result;
            }

            if (!CaseLogManager.Init())
            {
                result.success = false;
                result.message = "CaseLogManager Init Failed";
                return result;
            }

            Running = true;
            Closing = false;

            LocalDataManager.Init();

            ErrorFileManager.Init();

            //获取并加载当前PSD设备的下载任务列表
            var taskinfo = DownloadManager.RefreshTaskInfo();
            if (taskinfo.success)
            {
                Logger.Info("获取PSD设备下载任务成功：" + DownloadManager.DownloadTaskList.Count + "个任务");
                for (int i = 0; i < DownloadManager.DownloadTaskList.Count; i++)
                {
                    Logger.Text($"{i + 1}. {DownloadManager.DownloadTaskList[i].Task.task_name}");
                    for (int j = 0; j < DownloadManager.DownloadTaskList[i].ChannelList.Count; j++)
                    {
                        Logger.Text($"  ({j + 1}) {DownloadManager.DownloadTaskList[i].ChannelList[j].channel_name}");
                    }
                }
            }
            else
            {
                Logger.Error("获取PSD设备下载任务失败：" + taskinfo.message);
            }

            Logger.Info("初始化DownloadServiceContext");

            return result;
        }

        /// <summary>
        /// 打开当前PSD客户端
        /// </summary>
        public void OpenPSDClient()
        {
            DownloadManager.StartDownload();

            CaseLogManager.StartDownload();

            Logger.Info("PSDDownload已启动");
        }

        /// <summary>
        /// 关闭当前PSD客户端
        /// </summary>
        public void ClosePSDClient()
        {
            Closing = true;

            DownloadManager.StopDownload();

            CaseLogManager.StopDownload();

            Logger.Info("PSDDownload已停止");
        }

        /// <summary>
        /// 更新PSD配置信息
        /// </summary>
        public void UpdatePSDSetting(UpdatePSDSettingMessage msg)
        {
            var result = HttpHelper.Get<HResult<dl_download_device>>(AppSettings.Setting.API.GetDownloadDeviceInfo + "?deviceId=" + Device.id);

            if (result.success && result.data != null)
            {
                this.ClosePSDClient();

                AppSettings.Setting.ApiServerAddress = msg.ApiServerAddress;
                AppSettings.Setting.TcpServerAddress = msg.TcpServerAddress;
                AppSettings.Setting.TcpServerPort = msg.TcpServerPort;
                AppSettings.Setting.PSDListenPort = result.data.device_port;
                AppSettings.Setting.LogPath = result.data.log_path;
                AppSettings.Setting.DownloadDataPath = result.data.data_path;
                AppSettings.Setting.MaxDownloadProcess = result.data.max_download_process;
                AppSettings.Setting.StorageAvailablePercent = result.data.storage_available_percent;

                AppSettings.Setting.Save();

                this.Dispose();
                var ret = this.Init(this.RunAsService);

                if (ret.success)
                {
                    this.OpenPSDClient();
                }
            }
        }

        public void IgnoreDownloadFail(List<string> ignoreList)
        {
            ErrorFileManager.Pause();

            ErrorFileManager.IngoreErrorFile(ignoreList);

            ErrorFileManager.Continue();
        }

        #region Downloading State Message Response

        public void ResponseDownloadingFiles(IPEndPoint managerEP)
        {
            var msg = new ResponsePSDDownloadingFilesMessage();
            msg.DeviceId = UUID;
            msg.Files.AddRange(this.DownloadManager.DownloadingFiles);

            var ret = ClientContext.MessageManager.Send(managerEP, msg);

            if (!ret.success)
            {
                Logger.Error("同步当前下载文件信息失败：" + ret.message);
            }
        }
        #endregion

        public void Dispose(bool exit = true)
        {
            Running = false;
            Downloading = false;

            Thread.Sleep(2000);

            if (DownloadManager != null)
            {
                DownloadManager.Cleanup();
            }

            if (CaseLogManager != null)
            {
                CaseLogManager.Dispose();
            }

            if (LocalDataManager != null)
            {
                LocalDataManager.Dispose();
            }

            if (ErrorFileManager != null)
            {
                ErrorFileManager.Dispose();
            }

            if (exit)
            {
                Logger.Close();
            }
        }
    }
}
